home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet 2.7b5 / source / config / popup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-07  |  4.5 KB  |  206 lines  |  [TEXT/CWIE]

  1. /*
  2. *    popup.c
  3. *    Code for doing popup menus in our dialog boxes
  4. *    Credit for this goes to Apple Sample Code and a conglomeration of other code I've seen.
  5. *
  6. *****************************************************************
  7. *    NCSA Telnet for the Macintosh                                *
  8. *                                                                *
  9. *    National Center for Supercomputing Applications                *
  10. *    Software Development Group                                    *
  11. *    152 Computing Applications Building                            *
  12. *    605 E. Springfield Ave.                                        *
  13. *    Champaign, IL  61820                                        *
  14. *                                                                *
  15. *    Copyright (c) 1986-1992,                                    *
  16. *    Board of Trustees of the University of Illinois                *
  17. *****************************************************************
  18. *  Revisions:
  19. *  8/92        Telnet 2.6:    Initial version.  Jim Browne
  20. */
  21.  
  22. #ifdef MPW
  23. #pragma segment Configure
  24. #endif
  25.  
  26. #include "popup.h"
  27. #include "popup.proto.h"
  28.  
  29. static popup *FindPopup(short item);
  30. PROTO_UPP(DrawPopUp, UserItem);
  31.  
  32. popup *Popup;    /* Current popup structure array */
  33.  
  34. static popup *FindPopup( short item)
  35. {
  36.     popup *p = Popup;
  37.  
  38.     while (p->item) {
  39.             if (p->item == item)
  40.                 return p;
  41.             ++p;
  42.     }
  43.     return 0;                    /* Not found */
  44. }
  45.  
  46. SIMPLE_UPP(DrawPopUp, UserItem);
  47. pascal void DrawPopUp(DialogPtr dptr, short item)
  48. {
  49.     char text[256];
  50.     char* s;
  51.     PenState savePen;
  52.     Rect box, title;
  53.     FontInfo info;
  54.     short type, width, newwidth;
  55.     Handle hdl;
  56.     popup *p;
  57.  
  58.     GetPenState(&savePen);
  59.     GetFontInfo(&info);
  60.  
  61.     GetDItem(dptr, item, &type, &hdl, &box);
  62.     p = FindPopup(item);
  63.  
  64.     title = box;
  65.     title.right = box.left - 1;
  66.     title.left = title.right - StringWidth((**(p->h)).menuData) - 2;
  67.     box.top -= 1;
  68.     box.left -= 1;
  69.     box.bottom += 2;
  70.     box.right += 2;
  71.  
  72.     EraseRect(&box);
  73.     
  74.     if ((**(p->h)).menuData[0] != 0)
  75.         InvertRect(&title);
  76.  
  77.     /* Get and draw menu title. Get item text. */
  78.     if (!p || !p->h) return;
  79.     s = (char *)(**(p->h)).menuData;    /* Menu title */
  80.     MoveTo(box.left - StringWidth((StringPtr)s) - 2, box.top + info.ascent);
  81.     DrawString((StringPtr)s);
  82.     GetItem(p->h, p->choice, (StringPtr)text);
  83.  
  84.     width = (box.right - box.left) - (CharWidth(checkMark) + 2);
  85.     newwidth = StringWidth((StringPtr)text);
  86.  
  87.     if (newwidth > width) {
  88.         width -= CharWidth('…');
  89.         do {
  90.             newwidth -= CharWidth(text[text[0]]);
  91.             --text[0];
  92.             } while (newwidth > width && text[0]);
  93.         ++text[0];
  94.         text[text[0]] = '…';
  95.         }
  96.     
  97.     MoveTo(box.left + CharWidth(checkMark) + 2, box.top + info.ascent);
  98.     DrawString((StringPtr)text);
  99.  
  100.     InsetRect(&box, -1, -1);                    /* A la Apple Sample Code */
  101.     PenSize(1, 1);
  102.     FrameRect(&box);
  103.     MoveTo(box.left + 2, box.bottom);
  104.     LineTo(box.right, box.bottom);
  105.     LineTo(box.right, box.top + 2);
  106.  
  107.     SetPenState(&savePen);
  108. }
  109.  
  110. Boolean PopupMousedown(    DialogPtr dptr, EventRecord *event, short *i)
  111. {
  112.     short item, choice, type;
  113.     popup *p;
  114.     Point clikloc;
  115.     long chosen;
  116.     Handle hdl;
  117.     Rect box, title;
  118.     Boolean result = FALSE;
  119.  
  120.     clikloc = event->where;
  121.     GlobalToLocal(&clikloc);
  122.     if ((item = FindDItem(dptr, clikloc) + 1) < 1)
  123.         return result;
  124.     p = FindPopup(item);
  125.     if (!p || !p->h)
  126.         return result;
  127.  
  128.     GetDItem(dptr, item, &type, &hdl, &box);
  129.     clikloc = topLeft(box);
  130.     LocalToGlobal(&clikloc);
  131.     title = box;
  132.     title.right = box.left - 1;
  133.     title.left = title.right - StringWidth((**(p->h)).menuData) - 2;
  134.     box.top -= 1;
  135.     box.left -= 1;
  136.     box.bottom += 2;
  137.     box.right += 2;
  138.  
  139.     EraseRect(&box);
  140.     if ((**(p->h)).menuData[0] != 0)
  141.         InvertRect(&title);
  142.  
  143.     InsertMenu(p->h, hierMenu);
  144.     SetItemMark(p->h, p->choice, checkMark);
  145.     CalcMenuSize(p->h);
  146.     chosen = PopUpMenuSelect(p->h, clikloc.v, clikloc.h, p->choice);
  147.     SetItemMark(p->h, p->choice, noMark);
  148.     DeleteMenu((**(p->h)).menuID);
  149.  
  150.     if (chosen) {
  151.         choice = chosen & 0xFFFF;            /* Apple sez ignore high word */
  152.         if (choice != p->choice) {
  153.             p->choice = choice;
  154.             *i = item;
  155.             result = TRUE;
  156.         }
  157.     }
  158.  
  159.     DrawPopUp(dptr, item);
  160.  
  161.     return result;
  162. }
  163.  
  164. void PopupInit( DialogPtr dptr, popup *popups)
  165. {
  166.     popup *p;
  167.     short w;
  168.     FontInfo info;
  169.     short type;
  170.     Handle hdl;
  171.     Rect box;
  172.  
  173.     Popup = p = popups;
  174.     SetPort(dptr);
  175.     GetFontInfo(&info);
  176.     while (p->item) {
  177.         if (p->h) {
  178.             /* Correct user item box. */
  179.             GetDItem(dptr, p->item, &type, &hdl, &box);
  180.             CalcMenuSize(p->h);
  181.             w = (**(p->h)).menuWidth;
  182.             w += 16;
  183.             if (w < (box.right - box.left))
  184.                 box.right = box.left + w;
  185.             box.bottom = box.top + info.ascent + info.descent + info.leading;
  186.             SetDItem(dptr, p->item, type, (Handle)DrawPopUpUPP, &box);
  187.         }
  188.         ++p;
  189.     }
  190. }
  191.  
  192. void PopupCleanup(void)
  193. {
  194.     popup *p = Popup;
  195.  
  196.     while (p->item) {
  197.         if (p->h)
  198.             DisposeMenu(/*(Handle)*/p->h);    // Since we're using NewMenu's, we need
  199.                                             // to do a DisposeMenu, rather than a 
  200.                                             // Releaseresource
  201.         ++p;
  202.     }
  203. }
  204.  
  205.  
  206.